package com.thitech.sif.ws.soap;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.xml.namespace.QName;
import javax.xml.rpc.handler.Handler;
import javax.xml.rpc.handler.HandlerInfo;
import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;

import com.thitech.sif.ReqAndResContext;
import com.thitech.sif.utils.log.LogFactory;
import com.thitech.sif.utils.log.SifLogger;

/**
 * 在应用中使用JAXPRC 1.1.0标准的WebService客户端如(AXIS) 调用远程的WebService，要记录WebService的请求与响应
 * @author shisheng.lian
 * @date 2014-7-16
 */
public class LogSOAPMessageRPCHandler implements Handler {
	private SifLogger log = LogFactory.getLogger(getClass());

	public void init(HandlerInfo handlerInfo) {
	}

	public QName[] getHeaders() {
		return null;
	}

	public boolean handleFault(MessageContext soapContext) {
		SOAPMessageContext smc = (SOAPMessageContext) soapContext;
		logToCurrentThreadContext(smc, false);
		return true;
	}

	public boolean handleRequest(MessageContext soapContext) {
		SOAPMessageContext smc = (SOAPMessageContext) soapContext;
		logToCurrentThreadContext(smc, true);
		return true;
	}

	public boolean handleResponse(MessageContext soapContext) {
		SOAPMessageContext smc = (SOAPMessageContext) soapContext;
		logToCurrentThreadContext(smc, false);
		return true;
	}

	public void destroy() {
	}

	private void logToCurrentThreadContext(SOAPMessageContext smc, boolean isRequest) {
		SOAPMessage message = smc.getMessage();
		String logMessage = null;
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		try {
			message.writeTo(os);
			byte[] data = os.toByteArray();
			logMessage = new String(data, "UTF-8"); 
			os.flush();
		} catch (SOAPException e) {
			log.error("处理SOAP报文错误", e);
		} catch (IOException e) {
			log.error("处理SOAP报文错误", e);
		} finally {
			if (null != os) {
				try {
					os.close();
				} catch (Exception e) {
					//ignore
				}
			}
		}

		if (isRequest) {
			ReqAndResContext.currentContext().setRequest(logMessage); //输入
		} else {
			ReqAndResContext.currentContext().setResponse(logMessage); //输出
		}
	}

}
